home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / JFC.bin / AbstractFilter.java < prev    next >
Text File  |  1998-06-30  |  6KB  |  209 lines

  1. /*
  2.  * @(#)AbstractFilter.java    1.1 97/11/14
  3.  * 
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  */
  20. package com.sun.java.swing.text.rtf;
  21.  
  22. import java.io.*;
  23. import java.lang.*;
  24.  
  25. /**
  26.  * A generic superclass for streams which read and parse text
  27.  * consisting of runs of characters interspersed with occasional
  28.  * ``specials'' (formatting characters).
  29.  *
  30.  * <p> Most of the functionality
  31.  * of this class would be redundant except that the ByteToChar converters
  32.  * are suddently private API. Presumably this class will disappear
  33.  * when the API is made public again. (sigh) That will also let us handle
  34.  * multibyte character sets...
  35.  *
  36.  * <P> A subclass should override at least <code>write(char)</code>
  37.  * and <code>writeSpecial(int)</code>. For efficiency's sake it's a
  38.  * good idea to override <code>write(String)</code> as well. The subclass'
  39.  * initializer may also install appropriate translation and specials tables.
  40.  *
  41.  * @see OutputStream
  42.  */
  43. abstract class AbstractFilter extends OutputStream
  44. {
  45.     /** A table mapping bytes to characters */
  46.     protected char translationTable[];
  47.     /** A table indicating which byte values should be interpreted as
  48.      *  characters and which should be treated as formatting codes */
  49.     protected boolean specialsTable[];
  50.  
  51.     /** A translation table which does ISO Latin-1 (trivial) */
  52.     static final char latin1TranslationTable[];
  53.     /** A specials table which indicates that no characters are special */
  54.     static final boolean noSpecialsTable[];
  55.     /** A specials table which indicates that all characters are special */
  56.     static final boolean allSpecialsTable[];
  57.  
  58.     static {
  59.       int i;
  60.  
  61.       noSpecialsTable = new boolean[256];
  62.       for (i = 0; i < 256; i++)
  63.     noSpecialsTable[i] = false;
  64.  
  65.       allSpecialsTable = new boolean[256];
  66.       for (i = 0; i < 256; i++)
  67.     allSpecialsTable[i] = true;
  68.  
  69.       latin1TranslationTable = new char[256];
  70.       for (i = 0; i < 256; i++)
  71.     latin1TranslationTable[i] = (char)i;
  72.     }
  73.  
  74.     /**
  75.      * A convenience method that reads text from a FileInputStream
  76.      * and writes it to the receiver.
  77.      * The format in which the file
  78.      * is read is determined by the concrete subclass of 
  79.      * AbstractFilter to which this method is sent.
  80.      * <p>This method does not close the receiver after reaching EOF on
  81.      * the input stream.
  82.      * The user must call <code>close()</code> to ensure that all
  83.      * data are processed.
  84.      *
  85.      * @param in      An InputStream providing text.
  86.      */
  87.     public void readFromStream(InputStream in)
  88.       throws IOException
  89.     {
  90.         byte buf[];
  91.         int count;
  92.         
  93.     buf = new byte[16384];
  94.     
  95.     while(true) {
  96.         count = in.read(buf);
  97.         if (count < 0)
  98.             break;
  99.         
  100.         this.write(buf, 0, count);
  101.     }
  102.     }
  103.  
  104.  
  105.     public AbstractFilter()
  106.     {
  107.         translationTable = latin1TranslationTable;
  108.     specialsTable = noSpecialsTable;
  109.     }
  110.  
  111.     /**
  112.      * Implements the abstract method of OutputStream, of which this class
  113.      * is a subclass. 
  114.      */
  115.     public void write(int b)
  116.       throws IOException
  117.     {
  118.       if (b < 0)
  119.     b += 256;
  120.       if (specialsTable[b]) 
  121.     writeSpecial(b);
  122.       else {
  123.     char ch = translationTable[b];
  124.     if (ch != (char)0)
  125.       write(ch);
  126.       }
  127.     }
  128.  
  129.     /**
  130.      * Implements the buffer-at-a-time write method for greater
  131.      * efficiency. 
  132.      *
  133.      * <p> <strong>PENDING:</strong> Does <code>write(byte[])</code>
  134.      * call <code>write(byte[], int, int)</code> or is it the other way
  135.      * around?
  136.      */
  137.     public void write(byte[] buf, int off, int len)
  138.       throws IOException
  139.     {
  140.       StringBuffer accumulator = null;
  141.       while (len > 0) {
  142.         short b = (short)buf[off];
  143.  
  144.     // stupid signed bytes
  145.         if (b < 0)
  146.             b += 256;
  147.  
  148.     if (specialsTable[b]) {
  149.       if (accumulator != null) {
  150.         write(accumulator.toString());
  151.         accumulator = null;
  152.       }
  153.       writeSpecial(b);
  154.     } else {
  155.       char ch = translationTable[b];
  156.       if (ch != (char)0) {
  157.         if (accumulator == null)
  158.           accumulator = new StringBuffer();
  159.         accumulator.append(ch);
  160.       }
  161.     }
  162.     
  163.     len --;
  164.     off ++;
  165.       }
  166.  
  167.       if (accumulator != null) 
  168.     write(accumulator.toString());
  169.     }
  170.  
  171.     /**
  172.      * Hopefully, all subclasses will override this method to accept strings
  173.      * of text, but if they don't, AbstractFilter's implementation
  174.      * will spoon-feed them via <code>write(char)</code>. 
  175.      *
  176.      * @param s The string of non-special characters written to the
  177.      *          OutputStream.
  178.      */
  179.     public void write(String s)
  180.       throws IOException
  181.     {
  182.       int index, length;
  183.  
  184.       length = s.length();
  185.       for(index = 0; index < length; index ++) {
  186.     write(s.charAt(index));
  187.       }
  188.     }
  189.  
  190.     /**
  191.      * Subclasses must provide an implementation of this method which
  192.      * accepts a single (non-special) character.
  193.      *
  194.      * @param ch The character written to the OutputStream.
  195.      */
  196.     protected abstract void write(char ch) throws IOException;
  197.  
  198.     /**
  199.      * Subclasses must provide an implementation of this method which
  200.      * accepts a single special byte. No translation is performed
  201.      * on specials.
  202.      *
  203.      * @param b The byte written to the OutputStream.
  204.      */
  205.     protected abstract void writeSpecial(int b) throws IOException;
  206. }
  207.  
  208.  
  209.